package com.leyou.order.utils;

import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConfigImpl;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exceptions.LyException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 虎哥
 */
@Slf4j
@Component
public class PayHelper {

    @Autowired
    private WXPay wxPay;

    @Autowired
    private WXPayConfigImpl payConfig;

    public String generatePayUrl(Long orderId, Long total, String desc) {
        // 1.准备请求参数
        Map<String, String> data = new HashMap<String, String>();
        // 商品描述
        data.put("body", desc);
        // 订单的编号
        data.put("out_trade_no", orderId.toString());
        // 支付金额
        data.put("total_fee", total.toString());

        data.put("spbill_create_ip", payConfig.getSpbillCreateIp());
        data.put("notify_url", payConfig.getNotifyUrl());
        data.put("trade_type", payConfig.getTradeType());

        try {
            // 2.发起请求，获取响应
            Map<String, String> resp = wxPay.unifiedOrder(data);

            // 3.判断通信标识
            checkReturnCode(resp);
            // 4.判断业务标识
            checkResultCode(resp);
            // 5.验证通信签名
            checkSignature(resp);

            // 6.获取支付链接
            String url = resp.get("code_url");
            if (StringUtils.isBlank(url)) {
                // 支付链接获取失败
                throw new RuntimeException("支付链接为空!");
            }
            log.info("获取支付地址成功，订单编号：[{}], 支付地址：[{}]", orderId, url);
            return url;
        } catch (Exception e) {
            log.error("获取支付地址失败，原因：{}", e.getMessage(), e);
            throw new LyException(ExceptionEnum.WX_PAY_UNIFIED_ORDER_ERROR);
        }
    }

    public void checkReturnCode(Map<String, String> resp) {
        if ("FAIL".equals(resp.get("return_code"))) {
            // 通信失败，返回错误
            throw new RuntimeException(resp.get("return_msg"));
        }
    }

    public void checkResultCode(Map<String, String> resp) {
        if ("FAIL".equals(resp.get("result_code"))) {
            // 业务失败，返回错误
            throw new RuntimeException(resp.get("err_code_des"));
        }
    }

    public void checkSignature(Map<String, String> resp) throws Exception {
        boolean boo1 = WXPayUtil.isSignatureValid(resp, payConfig.getKey());
        boolean boo2 = WXPayUtil.isSignatureValid(resp, payConfig.getKey(), WXPayConstants.SignType.HMACSHA256);
        if(!boo1 && !boo2){
            // 签名验证失败！
            throw new RuntimeException("签名验证失败！再瞎搞我就报警了！");
        }
    }
}
